﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using lin;

public class UserToken
{
    const int BufferSize = 1024 * 8;
    byte[] buffer = new byte[BufferSize];

    TcpClient client;
    NetworkStream stream;

    MemoryStream mem;
    BinaryReader reader;
    public User user;
    public const int MaxHP=10;

    public UserToken(TcpClient client)
    {
        //和客户端的通信
        this.client = client;
        this.stream = client.GetStream();

        mem = new MemoryStream();
        reader = new BinaryReader(mem);

        //开启异步线程读取数据
        stream.BeginRead(buffer, 0, BufferSize, OnRead, client);
    }

    //异步读取的线程
    private void OnRead(IAsyncResult ar)
    {
        try
        {
            int readCount = client.GetStream().EndRead(ar);
            if (readCount <= 0) throw new Exception("流长度异常");

            OnReceive(buffer, readCount);

            //读取一次完毕，再次开启读取
            Array.Clear(buffer, 0, BufferSize);
            stream.BeginRead(buffer, 0, BufferSize, OnRead, client);
        }
        catch (Exception e)
        {
            Console.WriteLine("Exeption:{0},{1}",e.Message,e.StackTrace);
            Server.Instance.Disconnect(this);
        }
    }

    /// <summary>
    /// 解析数据的 逻辑层
    /// </summary>
    /// <param name="bytes"></param>
    /// <param name="length"></param>
    void OnReceive(byte[] bytes, int length)
    {
        //追加数据到缓存
        mem.Seek(0, SeekOrigin.End);
        mem.Write(bytes, 0, length);
        mem.Seek(0, SeekOrigin.Begin);

        //根据长度解析每条数据
        int LenCount = 2;//长度所占字节
        while (RemainingBytes() > LenCount)
        {
            //获取消息长度
            ushort len = reader.ReadUInt16();
            if (RemainingBytes() >= len)
            {
                //解析出一条消息
                byte[] result = reader.ReadBytes(len);
                OnMessage(result);
            }
            else
            {
                //字节流长度不够len，往前退两位，跳出循环
                mem.Position = mem.Position - LenCount;
                break;
            }
        }

        //把剩余字节重新写入缓存
        byte[] left = reader.ReadBytes(RemainingBytes());
        mem.SetLength(0);
        mem.Write(left, 0, left.Length);
    }

    int RemainingBytes()
    {
        return (int)(mem.Length - mem.Position);
    }

    //接受到一条消息
    void OnMessage(byte[] bytes)
    {
        ByteBuffer byteBuffer = new ByteBuffer(bytes);
        ushort command = byteBuffer.ReadShort();//读取命令
        byte[] content = byteBuffer.ReadBytes();//读取bytes

        Server.Instance.OnMessage(this, (Protocol)command, content);
    }

    //主动发送消息
    //协议基础：[len][command][message]
    public void Send(byte[] message)
    {
        //获取message的byte长度
        ushort msglen = (ushort)message.Length;

        //把长度和消息写到一起
        ByteBuffer bytebuffer = new ByteBuffer();
        bytebuffer.WriteShort(msglen);
        bytebuffer.WriteBytes(message);

        try
        {
            //获取最终byte数组
            byte[] result = bytebuffer.ToBytes();
            stream.BeginWrite(result, 0, result.Length, OnWrite, null);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message+":"+e.StackTrace);
        }
    }

    public void Send(Protocol command, byte[] content)
    {
        ByteBuffer bytebufer = new ByteBuffer();
        bytebufer.WriteShort((ushort)command);
        bytebufer.WriteBytes(content);

        Send(bytebufer.ToBytes());
    }

    ////主动发送消息
    //public void Send(int commamd, string json)
    //{
    //    byte[] bytes = Encoding.UTF8.GetBytes(json);
    //    Send((Protocol)commamd, bytes);
    //}

    //异步发送回调
    private void OnWrite(IAsyncResult ar)
    {
        stream.EndWrite(ar);
    }
}



